package org.osami.identification.impl;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Hashtable;

import org.osami.identification.NodeIdentification;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator  implements BundleActivator{
	private byte[] iMac;
	
	public native byte[] getMAC();
	
	static {
		System.loadLibrary("osamimac");
	}
	@Override
	public void start(BundleContext context) throws Exception {
		InetAddress address = getLocalAddress();
		readMacAddress(address);
		
		Hashtable<String, String> props = new Hashtable<String, String>();
		props.put("description", "OSAmI Commons Node Identification");
		context.registerService(NodeIdentification.class.getName(), new NodeIdentificationImpl(getMacId()), props);
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		// TODO Auto-generated method stub
		
	}
	/**
	 * Return computers real IP address. This is crap shoot since the returned address is 
	 * the last read non-loopback address. Better approad would be to return an array of addresses
	 * which are real, then client would work also on gateway device with multiple interfaces. 
	 * @return address of last real network interface
	 * @throws UnknownHostException
	 */
	private InetAddress getLocalAddress() throws UnknownHostException {
		InetAddress localAddr = InetAddress.getLocalHost();
		//String localAddr = locallAddr.getHostAddress();
		
		if (localAddr.isLoopbackAddress())
		{
			System.out.println("Error local address is loopback!!");
			NetworkInterface iface = null;
			try {
				for(Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();ifaces.hasMoreElements();){
					iface = (NetworkInterface)ifaces.nextElement();
					System.out.println("Interface:"+ iface.getDisplayName());
					InetAddress ia = null;
					for(Enumeration ips = iface.getInetAddresses();ips.hasMoreElements();){
						ia = (InetAddress)ips.nextElement();
						if (!ia.isLoopbackAddress())
						{
							System.out.println("Found non loopback addr: " + ia.toString());
							localAddr = ia;
							//localAddr = ia.getHostAddress();
						}
						System.out.println(ia.getCanonicalHostName()+" "+ ia.getHostAddress());
					}
				}
			} catch (SocketException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		}
		return localAddr;
	}
	
	private void readMacAddress(InetAddress address)
	{	
		/*
		try {
			//
			 // Get NetworkInterface for the current host and then read the
			 // hardware address.
			 //
			NetworkInterface ni = NetworkInterface.getByInetAddress(address);
			if (ni != null) {
				byte[] mac = ni.getHardwareAddress();
				if (mac != null) {
					iMac = mac;
				} else {
					System.out.println("Address doesn't exist or is not accessible.");
				}
			} else {
				System.out.println("Network Interface for the specified address is not found.");
			}
		} catch (SocketException e) {
			e.printStackTrace();
		}
		System.out.println("ID is: "+getMacId());
		*/
		iMac = getMAC();
	}
	
	private String getMacId() {
		String ID = "";
		if (iMac != null) {
			/*
			 * Extract each array of mac address and convert it to hexa with the
			 * following format 08-00-27-DC-4A-9E.
			 */
			PrintStream idout;

			ByteArrayOutputStream outstr = new ByteArrayOutputStream();
			idout = new PrintStream(outstr);
			for (int i = 0; i < iMac.length; i++) {
				

				idout.format("%02X%s", iMac[i], (i < iMac.length - 1) ? "-" : "");
				ID = "mac:"+outstr.toString();
			}
		} else {
			System.out.println("Address doesn't exist or is not accessible.");
		}
		System.out.println("return ID " + ID);
		return ID;
	}
}
